package org.altervista.cp.thinbcgen.bean.test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.bcel.Constants;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.Type;

public class SubJavaBeanCreator implements Constants {
	private InstructionFactory _factory;
	private ConstantPoolGen _cp;
	private ClassGen _cg;

	public SubJavaBeanCreator() {
		_cg = new ClassGen("org.altervista.cp.thinbcgen.bean.test.SubJavaBean",
				"org.altervista.cp.thinbcgen.bean.test.JavaBean",
				"SubJavaBean.java", ACC_PUBLIC | ACC_SUPER, new String[] {});

		_cp = _cg.getConstantPool();
		_factory = new InstructionFactory(_cg, _cp);
	}

	public void create(OutputStream out) throws IOException {
		createMethod_0();
		createMethod_1();
		_cg.getJavaClass().dump(out);
	}

	private void createMethod_0() {
		InstructionList il = new InstructionList();
		MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS,
				new String[] {}, "<init>",
				"org.altervista.cp.thinbcgen.bean.test.SubJavaBean", il, _cp);

		InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
		il.append(_factory.createInvoke(
				"org.altervista.cp.thinbcgen.bean.test.JavaBean", "<init>",
				Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
		InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID));
		method.setMaxStack();
		method.setMaxLocals();
		_cg.addMethod(method.getMethod());
		il.dispose();
	}

	private void createMethod_1() {
		InstructionList il = new InstructionList();
		MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID,
				new Type[] { Type.INT }, new String[] { "arg0" }, "<init>",
				"org.altervista.cp.thinbcgen.bean.test.SubJavaBean", il, _cp);

		InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0));
		il.append(_factory.createLoad(Type.INT, 1));
		il.append(_factory.createInvoke(
				"org.altervista.cp.thinbcgen.bean.test.JavaBean", "<init>",
				Type.VOID, new Type[] { Type.INT }, Constants.INVOKESPECIAL));
		InstructionHandle ih_5 = il.append(_factory.createReturn(Type.VOID));
		method.setMaxStack();
		method.setMaxLocals();
		_cg.addMethod(method.getMethod());
		il.dispose();
	}

	public static void main(String[] args) throws Exception {
		org.altervista.cp.thinbcgen.bean.test.SubJavaBeanCreator creator = new org.altervista.cp.thinbcgen.bean.test.SubJavaBeanCreator();
		creator.create(new FileOutputStream(
				"org.altervista.cp.thinbcgen.bean.test.SubJavaBean.class"));
	}
}
